using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using StudentManagement.Application.DTOs;
using StudentManagement.Application.Services;
using StudentManagement.Application.Settings;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;

namespace StudentManagement.API.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class AuthController : ControllerBase
    {
        private readonly IUserService _userService;
        private readonly JwtSettings _jwtSettings;

        public AuthController(IUserService userService, IOptions<JwtSettings> jwtSettingsOptions)
        {
            _userService = userService;
            _jwtSettings = jwtSettingsOptions.Value;
        }

        /// <summary>
        /// 用户登录
        /// </summary>
        [HttpPost("login")]
        public async Task<ActionResult<LoginResponse>> Login([FromBody] LoginDTO loginDTO)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            var (isValid, userId, username, roles) = await _userService.ValidateUserAsync(loginDTO.Username, loginDTO.Password);

            if (!isValid)
            {
                return Unauthorized("用户名或密码错误");
            }

            var token = GenerateJwtToken(userId, username, roles);

            return Ok(new LoginResponse
            {
                Token = token,
                Username = username,
                Roles = roles
            });
        }

        /// <summary>
        /// 用户注册
        /// </summary>
        [HttpPost("register")]
        public async Task<ActionResult<UserDTO>> Register([FromBody] RegisterDTO registerDTO)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            try
            {
                var user = await _userService.RegisterAsync(registerDTO);
                return CreatedAtAction(nameof(UserController.GetUserById), "User", new { id = user.Id }, user);
            }
            catch (System.Exception ex)
            {
                return BadRequest(ex.Message);
            }
        }

        /// <summary>
        /// 获取当前用户信息
        /// </summary>
        [Authorize]
        [HttpGet("user-info")]
        public async Task<ActionResult<UserInfoResponse>> GetUserInfo()
        {
            var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
            if (userId == null)
            {
                return Unauthorized();
            }

            var user = await _userService.GetUserByIdAsync(int.Parse(userId));
            if (user == null)
            {
                return NotFound("用户不存在");
            }

            var roles = await _userService.GetUserRolesAsync(int.Parse(userId));

            return Ok(new UserInfoResponse
            {
                Id = user.Id,
                Username = user.Username,
                Roles = roles
            });
        }

        /// <summary>
        /// 退出登录
        /// </summary>
        [Authorize]
        [HttpPost("logout")]
        public IActionResult Logout()
        {
            // 在JWT认证中，服务器端不需要处理登出逻辑
            // 客户端应该删除存储的token
            return Ok(new { message = "退出登录成功" });
        }

        /// <summary>
        /// 生成JWT令牌
        /// </summary>
        private string GenerateJwtToken(int userId, string username, List<string> roles)
        {
            var tokenHandler = new JwtSecurityTokenHandler();
            var key = Encoding.ASCII.GetBytes(_jwtSettings.SecretKey);

            var claims = new List<Claim>
            {
                new Claim(ClaimTypes.NameIdentifier, userId.ToString()),
                new Claim(ClaimTypes.Name, username)
            };

            // 添加角色声明
            foreach (var role in roles)
            {
                claims.Add(new Claim(ClaimTypes.Role, role));
            }

            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Subject = new ClaimsIdentity(claims),
                Expires = DateTime.UtcNow.AddHours(_jwtSettings.ExpirationHours),
                Issuer = _jwtSettings.Issuer,
                Audience = _jwtSettings.Audience,
                SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
            };

            var token = tokenHandler.CreateToken(tokenDescriptor);
            return tokenHandler.WriteToken(token);
        }
    }
}